local STR = require("modules/str")
DEBUG = false

hs.application.enableSpotlightForNameSearches(true)

local keyHook = {}

local function inputText(test)
    local rt = split(test, '\n')
    for _, s in ipairs(rt) do
        if s == "{tab}" then
            hs.eventtap.keyStroke({}, 'tab')
        elseif s == "{enter}" then
            hs.eventtap.keyStroke({}, 'return')
        else
            hs.eventtap.keyStrokes(s)
        end
    end
end

local function do_shell_exec(cmd)
    hs.task.new('/usr/bin/env',function()
    end, {'zsh','-c',"eval `/usr/libexec/path_helper -s`;"..cmd}):start()
end

-- 绑定窗口信息快捷功能
hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, "i", function()
    hs.alert.show("App path:        " .. hs.window.focusedWindow():application():path() .. "\n" ..
                  "App name:        " .. hs.window.focusedWindow():application():name() .. "\n" ..
                  "Window Title:    " .. hs.window.focusedWindow():title() .. "\n" .. 
                  "IM source id:    " .. hs.keycodes.currentSourceID(),
                  10)
    hs.pasteboard.setContents(hs.window.focusedWindow():application():name())
end)

-- Well, sometimes auto-reload is not working, you know u.u
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "n", function() hs.reload() end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "c", function() hs.execute('/usr/local/bin/code-insiders ~/.hammerspoon') end)

hs.hotkey.bind({"cmd", "alt", "ctrl"}, "t", function() inputText(os.date("%Y-%m-%d %H:%M:%S")) end)

--- - 日志功能
function logShow(message) if (DEBUG) then hs.alert.show(message,2) end end

logShow("等待网络连接")
-- 等待网络连接
while (true) do
    local _, state = os.execute("ping -c 1 -W 0.5 255.255.255.255")
    if (state) then
        logShow("网络已连接")
        break
    end
    os.execute("sleep .1")
end

logShow("解密密码")
data = hs.execute('cat ~/.hammerspoon/password|openssl aes-128-cbc -d -k gh8p9bqi5vRiUf -base64'):gsub("^%s*(.-)%s*$", "%1")
session = hs.execute('cat ~/.hammerspoon/session'):gsub("^%s*(.-)%s*$", "%1")

if data == "" then
    logShow("主密码未设置")
    print('没有设置主密码，请使用命令`echo "<password>" | openssl aes-128-cbc -k gh8p9bqi5vRiUf -base64 > ~/.hammerspoon/password`设置密码')
    hs.alert.show('没有设置主密码，请使用命令`echo "<password>" | openssl aes-128-cbc -k gh8p9bqi5vRiUf -base64 > ~/.hammerspoon/password`设置密码', 20)
end

if session == "" then
    hs.alert.show('没有设置密码库session，请先安装bw然后通过bw login获取session，并将session写入~/.hammerspoon/session', 20)
end

logShow("执行启动脚本")
do_shell_exec('bash ~/.hammerspoon/rc.local >/dev/null 2>&1 &')

logShow("启动系统检察者")
function muteOnWake(eventType)
    if (eventType == hs.caffeinate.watcher.systemDidWake) then -- 系统从睡眠中醒来
        logShow("系统从睡眠中醒来")
        do_shell_exec('bash ~/.hammerspoon/Spoons/systemDidWake.sh >/dev/null 2>&1 &')
    elseif (eventType == hs.caffeinate.watcher.screensDidWake) then
        do_shell_exec('bash ~/.hammerspoon/Spoons/systemDidWake.sh >/dev/null 2>&1 &')
    elseif (eventType == hs.caffeinate.watcher.screensDidUnlock) then
        do_shell_exec('bash ~/.hammerspoon/Spoons/systemDidWake.sh >/dev/null 2>&1 &')
    end
end

caffeinateWatcher = hs.caffeinate.watcher.new(muteOnWake)
caffeinateWatcher:start()

logShow("绑定密码快捷键")
function split(str, split_char)
    local sub_str_tab = {}
    while true do
        local pos = string.find(str, split_char)
        if not pos then
            table.insert(sub_str_tab, str)
            break
        end
        local sub_str = string.sub(str, 1, pos - 1)
        table.insert(sub_str_tab, sub_str)
        str = string.sub(str, pos + 1, string.len(str))
    end
    return sub_str_tab
end

local function inputPassword()
    local appPath = hs.window.focusedWindow():application():path()
    local appName = hs.window.focusedWindow():application():name()
    local winTitle = hs.window.focusedWindow():title()
    local result = hs.execute('/usr/local/bin/node ~/.hammerspoon/script/get_passwd.js ' ..'"' .. appPath .. '" "' .. appName .. '" "' ..winTitle .. '"')
    if result:find("^success:") == nil then
        print("result is: " .. result)
        hs.alert.show(result:gsub("^%s*(.-)%s*$", "%1"), 5)
    else
        local test = result:gsub("^%s*success:(.-)%s*$", "%1")
        inputText(test)
    end
end

table.insert(keyHook, hs.hotkey.bind({'cmd'}, "\\", inputPassword))

table.insert(keyHook, hs.hotkey.bind({"shift", "cmd"}, "\\", function()
    local result = hs.execute('/usr/local/bin/node ~/.hammerspoon/script/get_passwd.js --update --message')
    print(result)
    hs.alert.show(result:gsub("^%s*(.-)%s*$", "%1"), 5)
end))

-- 自启动
logShow("启动自启动软件")
function autoStartOpen(appPath,mini)
    hs.task.new('/usr/bin/open',function()
        local name=hs.execute("osascript -e 'id of app \""..appPath.."\"'"):gsub("^%s*(.-)%s*$", "%1")
        local wlist = hs.application.find(name):allWindows()
        while(#wlist==0)
        do
            wlist = hs.application.find(name):allWindows()
        end
        if mini == true then 
            for i = 1, #wlist do wlist[i]:minimize() end
        else
            hs.application.find(name):hide()
        end
    end, {appPath}):start()
end
autoStartOpen("/System/Applications/Mail.app",true)
autoStartOpen("/Applications/iTerm.app")
autoStartOpen("/Applications/Telegram.app")

-- 定时任务
function doEveryAll()
    hs.task.new('/usr/local/bin/python3',function(code,status,stderr) 
        status=status:gsub("^%s*(.-)%s*$", "%1")
        if (#status > 0) then
            if (status == "off" or status == "on") then
                hs.execute('/usr/local/bin/dark-mode '..status)
            else
                print("status无法识别"..status)
                hs.alert.show("设置黑暗模式失败")
            end
        elseif (#stderr > 0) then
            print(stderr)
            hs.alert.show("设置黑暗模式失败")
        end
    end,{'script/get_dark_mode_status.py'}):start()
end
timer30 = hs.timer.new(30,doEveryAll)
timer30:start()
doEveryAll()

-- 输入法自动控制
logShow("启动输入法自动控制")
function inputEnglish()
    if (hs.keycodes.currentSourceID() == "com.apple.keylayout.ABC") then
        return
    end
    hs.keycodes.currentSourceID("com.apple.keylayout.ABC")
    logShow("切换到英文输入法")
end

function inputChinese()
    if (hs.keycodes.currentSourceID() == "com.apple.inputmethod.SCIM.Shuangpin") then
        return
    end
    hs.keycodes.currentSourceID("com.apple.inputmethod.SCIM.Shuangpin")
    logShow("切换到中文输入法")
end

englishAppList = {}
lastCheckAppName = ''
disableKeyhotApplication = {"屏幕共享","Code - Insiders","WebStorm"}

function touchKeyhot(status)
    for _, v in pairs(keyHook) do
        if status then
            v:enable()
        else
            v:disable()
        end
    end
end

function checkImeMethod(_)
    local window = hs.window.focusedWindow()
    if (window == nil) then return end
    local application = window:application()
    if (application == nil) then return end
    local name = application:name()
    if (name == lastCheckAppName) then return end
    for _, v in pairs(englishAppList) do
        if (name == v) then
            inputChinese()
            lastCheckAppName = name
            return
        end
    end
    inputEnglish()
    lastCheckAppName = name
    local enableKeyHot = true
    for _, v in pairs(disableKeyhotApplication) do
        if v == name then
            enableKeyHot = false
            break
        end
    end
    if (enableKeyHot == true) then
        print('启用热键: ' .. name)
        touchKeyhot(true)
    else
        print('禁用热键: ' .. name)
        touchKeyhot(false)
    end
end

hs.hotkey.bind({'ctrl', 'alt', 'cmd'}, "y", function()
    local str = hs.pasteboard.getContents()
    local sub_str_tab = {}
    while true do
        local sub_str = STR.SubStringUTF8(str, 1, 1)
        table.insert(sub_str_tab, sub_str)
        str = STR.SubStringUTF8(str, 2)
        if(string.len(str)==0) then
            break
        end
    end
    os.execute("sleep 2")
    for _, s in ipairs(sub_str_tab) do
        os.execute("sleep .01")
        hs.eventtap.keyStrokes(s)
    end
end)

hs.window.filter.new(true):subscribe(hs.window.filter.windowCreated, checkImeMethod)
hs.window.filter.new(true):subscribe(hs.window.filter.windowFocused, checkImeMethod)
hs.window.filter.new(true):subscribe(hs.window.filter.windowDestroyed, checkImeMethod)

hs.alert.show("Config loaded",2)
